<?php

namespace app\api\controller;

use app\api\ApiBaseController;
use app\common\service\Request;
use app\common\service\Wechat;
use app\pilot\model\BalanceRecordModel;
use app\pilot\model\PilotModel;
use app\pilot\model\ToCashModel;
use app\task\model\OrderModel;
use app\task\model\TaskModel;
use think\Exception;
use think\facade\Db;

/**
 * 飞手
 */
class Pilot extends ApiBaseController
{
    /**
     * 不需要验证登录的接口
     * @var bool
     */
    public $noNeedLoginAuth = ['login'];

    /**
     * 登录
     */
    public function login()
    {
        try{
            $input = $this->request->post();
            // 微信code
            $code = $input['code'] ?? '';
            // 推荐人id
            $referer_id    = $input['referer_id'] ?? 0;
            if (empty($code)) $this->error('缺少code');
            // 请求微信接口获取openid和unionid
            $res = Wechat::WeMiniCrypt('pilot')->session($code);
            $openid = $res['openid'] ?? '';
            if (empty($openid)) $this->error('缺少openid');
            $unionid = $res['unionid'] ?? '';
            $pilot = PilotModel::where('openid', $openid)->findOrEmpty();
            $token = rand_str();

            Db::startTrans();
            $timeout = strtotime("+15 days");
            if ($pilot->isEmpty()) {
                $referer = PilotModel::where('referer_id', $referer_id)->find();
                if (!empty($referer)) $pilot->referer_id = $referer_id;
                $pilot->openid = $openid;
                $pilot->unionid = $unionid;
                $pilot->nickname = '微信用户';
                $pilot->token = $token;
                $pilot->timeout = $timeout;
            }else{
               if (time() > $pilot->timeout - 200){
                   $pilot->token = $token;
                   $pilot->timeout = $timeout;
               }
            }
            $pilot->login_at = date('Y-m-d H:i:s');
            $pilot->login_num += 1;
            $pilot->login_ip = $this->app->request->ip();
            $pilot->save();
            Db::commit();
            $result = [
                'token'     => $pilot->token,
                'timeout'  => $pilot->timeout,
            ];
            $this->success('ok', $result);
        }catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }
    }

    /**
     * 微信获取手机号
     */
    public function wxGetPhone()
    {
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');

        $input = $this->request->post();
        // 微信code，换取手机号
        $code = $input['code'] ?? '';

        $pilot = PilotModel::where('id', $pilot['id'])->find();
        try {
            $res = Wechat::WeMiniCrypt('pilot')->getPhoneNumber($code);
            $pilot->phone = $res['phone_info']['phoneNumber'];
            $pilot->save();
        }catch (Exception $e){
            $this->error($e->getMessage());
        }
        $this->success('ok', [
            'phone' => $pilot->phone,
        ]);
    }

    /**
     * 飞手个人信息
     */
    public function userInfo()
    {
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');

        $user_info = array_keep($pilot, [
            'nickname','avatar','phone','qq','email','balance','realname', 'id_card', 'native_place','address','education','gender','province','city','country','caac_certificate_no','utc_certificate_no', 'other_certificate_name', 'other_certificate_no'
        ]) ;
        $this->success('ok', $user_info);
    }

    /**
     * 更新飞手个人信息
     */
    public function saveInfo()
    {
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');
        if (empty($pilot['phone'])) $this->error('请先登录');

        $pilot = PilotModel::where('id', $pilot['id'])->find();
        $input = $this->request->post();
        // 更新昵称头像
        if (!empty($input['nickname'])) $pilot->nickname = $input['nickname'];
        if (!empty($input['avatar'])) $pilot->avatar = $input['avatar'];
        // 更新实名信息
        if (!empty($input['realname'])) $pilot->realname = $input['realname'];
        if (!empty($input['id_card'])) {
            $pilot->id_card = $input['id_card'];
            // 定义身份证号码的正则表达式
            $regex = '/^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/';
            if (!preg_match($regex, $pilot->id_card)) $this->error('身份证号码格式错误');
        }
        // 更新学历及相关证书
        if (isset($input['education'])) $pilot->education = $input['education'];
        if (isset($input['education_img'])) $pilot->education_img = $input['education_img'];
        if (isset($input['caac_certificate_no'])) $pilot->caac_certificate_no = $input['caac_certificate_no'];
        if (isset($input['utc_certificate_no'])) $pilot->utc_certificate_no = $input['utc_certificate_no'];
        if (isset($input['other_certificate_name'])) $pilot->other_certificate_name = $input['other_certificate_name'];
        if (isset($input['other_certificate_no'])) $pilot->other_certificate_no = $input['other_certificate_no'];
        $pilot->save();
        $this->success('ok');
    }


    /**
     * 配置数据
     */
    public function config()
    {
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');

        $config['service_wechat_qrcode']  = sysconf('service_wechat_qrcode');
        $config['service_phone']  = sysconf('service_phone');
        $config['service_time']  = sysconf('service_time');

        $this->success('ok', $config);
    }

    /**
     * 配置数据
     */
    public function note()
    {
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');

        $config['pilot_note']  = htmlspecialchars_decode(sysconf('pilot_note'));

        $this->success('ok', $config);
    }


    /**
     * 飞手用户协议
     */
    public function agreement()
    {
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');

        $config['pilot_agreement']  = htmlspecialchars_decode(sysconf('pilot_agreement'));

        $this->success('ok', $config);
    }

    /**
     * 获取分享二维码
     */
    public function qrcode()
    {
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');

        $baseurl = dirname(request()->baseFile(true));
        $separator = DIRECTORY_SEPARATOR;
        $filepath = "upload{$separator}qrcode{$separator}pilot{$separator}{$pilot['openid']}.png";
        $url = $baseurl.$separator.$filepath;
        if (file_exists($filepath)){
            $this->success('ok', $url);
        }else{
            // 获取二维码
            try {
                $referer_id = $pilot['id'] ?? 0;
                $res = Wechat::WeMiniQrcode('pilot')->createMiniScene($referer_id, '', 300, false, null, true);
                if (!is_dir(dirname($filepath))) mkdir(dirname($filepath), 0777, true);
                if (file_put_contents($filepath, $res)) {
                    $this->success('ok', $url);
                } else {
                    $this->error('二维码保存失败');
                }
            }catch (Exception $e){
                $this->error($e->getMessage());
            }
        }
    }


    /**
     * 订单任务订单列表
     */
    public function taskOrderList()
    {
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');

        $query = OrderModel::where(['is_deleted'=>0])->with(['task'=>['category', 'transport']])
            ->where('pilot_id', $pilot['id'])
            ->order('id desc');
        // 筛选项
        $type = $this->request->post('type', '');
        $type = strval($type);
        if ($type === '1'){
            $query->whereIn('status', [OrderModel::STATUS__APPLYING, OrderModel::STATUS__STANDBY]);
        }else if ($type === '2'){
            $query->where('status', OrderModel::STATUS__PENDING_COMPLETION);
        }else if ($type === '3'){
            $query->where('status', OrderModel::STATUS__PENDING_REVIEW);
        }else if ($type === '4'){
            $query->whereIn('status', [OrderModel::STATUS__COMPLETED, OrderModel::STATUS__REVIEW_FAILED]);
        }else if ($type === '5'){
            $query->where('status', OrderModel::STATUS__CANCELED);
        }
        $list = get_list($query);
        // 数据清洗
        foreach ($list['list'] as &$vo){
            if(!empty($vo['task'])) {
                $transport = $vo['task']['transport'];
                $vo['task'] = array_keep($vo['task'], ['id','name','exec_at','place','money','category_id','task_status','category']);
                $vo['task']['exec_at'] = date('Y-m-d H:i', strtotime($vo['task']['exec_at']));
                $vo['task']['category'] = array_keep($vo['task']['category'], ['id', 'name', 'img']);
                $vo['task']['money'] = get_task_pilot_money($vo['task']['money']);

                $vo['task']['transport_type'] = $transport['type'] ?? '';
                $vo['task']['transport_distance'] = $transport['distance'] ?? '';
                $vo['task']['transport_scene'] = $transport['scene'] ?? '';
                $vo['task']['weight'] = $transport['weight'] ?? '';
            }
        }
        $this->success('ok', $list);
    }

    /**
     * 订单任务订单详情
     */
    public function orderDetail(){
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');

        $id = $this->request->post('id', 0);
        $order = OrderModel::where(['is_deleted'=>0])->with(['task'=>['category','transport']])
            ->where('pilot_id', $pilot['id'])
            ->where('id', $id)
            ->find();
        if (empty($order)) $this->error('订单任务订单不存在');
        $order = $order->toArray();
        $order['task'] = array_keep($order['task'], ['id','name','exec_at','place','money','category_id','task_status','require','desc','category', 'transport']);
        if(isset($order['task'])) {
            $order['task']['exec_at'] = date('Y-m-d H:i', strtotime($order['task']['exec_at']));
            $order['task']['category'] = array_keep($order['task']['category'], ['id', 'name', 'img']);
            $order['task']['money'] = get_task_pilot_money($order['task']['money']);
            // 添加货运信息
            if ($order['task']['category_id'] == 1){
                $task = $order['task'];
                $transport = $order['task']['transport'];
                unset($order['task']['transport']);
                $task['start_at'] = date('Y-m-d H:i', strtotime($transport['start_at'] ?? ''));
                $task['end_at'] =  date('Y-m-d H:i', strtotime($transport['end_at'] ?? ''));
                $task['transport_type'] = $transport['type'] ?? '';
                $task['transport_scene'] = $transport['scene'] ?? '';
                $task['transport_distance'] = $transport['distance'] ?? '';
                $task['weight'] = $transport['weight'] ?? '';
                $task['province'] = $transport['province'] ?? '';
                $task['city'] = $transport['city'] ?? '';
                $task['area'] = $transport['area'] ?? '';
                $task['address'] = $transport['address'] ?? '';
                $task['place'] = $transport['place'] ?? '';
                $task['lat'] = $transport['lat'] ?? '';
                $task['lng'] = $transport['lng'] ?? '';
                $task['latlng'] = $transport['latlng'] ?? '';
                $task['province2'] = $transport['province2'] ?? '';
                $task['city2'] = $transport['city2'] ?? '';
                $task['area2'] = $transport['area2'] ?? '';
                $task['address2'] = $transport['address2'] ?? '';
                $task['place2'] = $transport['place2'] ?? '';
                $task['lat2'] = $transport['lat2'] ?? '';
                $task['lng2'] = $transport['lng2'] ?? '';
                $task['latlng2'] = $transport['latlng2'] ?? '';
                $task['transport_type_other'] = $transport['type_other'] ?? '';
                $task['transport_scene_other'] = $transport['scene_other'] ?? '';
                $order['task'] = $task;
            }
        }
        $this->success('ok', $order);
    }

    /**
     * 订单接单申请
     */
    public function taskAccept(){
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');
        if (empty($pilot['phone'])) $this->error('请先登录');

        // 实名认证
        if (empty($pilot['realname']) || empty($pilot['id_card'])) $this->error('请先实名认证');

        $id = $this->request->post('id', 0);
        Db::startTrans();
        try {
            $task = TaskModel::where(['is_deleted'=>0, 'status'=>1])
                ->where('task_status', TaskModel::TASK_STATUS__PENDING_ACCEPTANCE)
                ->whereTime('exec_at', '>', date('Y-m-d H:i:s'))
                ->where('id', $id)
                ->lock(true)
                ->find();
            if (empty($task)) $this->error('订单任务不存在');
            // 是否已经提出申请
            $task_order = OrderModel::where('is_deleted', 0)->where('task_id', $task->id)->where('pilot_id', $pilot['id'])->find();
            if (!empty($task_order)) $this->error('您已提交过接单申请');
            // 创建订单
            $order = [
                'task_id' => $task->id,
                'pilot_id' => $pilot['id'],
                'receive_at' => date('Y-m-d H:i:s'),
                'status' => OrderModel::STATUS__APPLYING,
                'update_at' =>date('Y-m-d H:i:s'),
                'money' => get_task_pilot_money($task->money)
            ];
            $order['order_no'] = OrderModel::createOrderNum();
            $order = OrderModel::create($order);
            // 更新任务状态
//            $task->order_id = $order->id;
//            $task->task_status = TaskModel::TASK_STATUS__PENDING_COMPLETION;
//            $task->save();
            Db::commit();
        }catch (Exception $e){
            Db::callback();
            $this->error($e->getMessage());
        }
        $this->success('ok');
    }

    /**
     * 订单任务订单完成
     */
    public function orderComplete(){
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');
        if (empty($pilot['phone'])) $this->error('请先登录');

        $id = $this->request->post('id', 0);
        Db::startTrans();
        try {
            $order = OrderModel::where(['is_deleted'=>0])
                ->where('pilot_id', $pilot['id'])
                ->where('id', $id)
                ->lock(true)
                ->find();
            if (empty($order)) $this->error('订单任务订单不存在');
            if ($order->status != OrderModel::STATUS__PENDING_COMPLETION) $this->error('待完成的订单任务才能完成');
            // 更新任务状态
            $order->status = OrderModel::STATUS__PENDING_REVIEW;
            $order->complete_at = date('Y-m-d H:i:s');
            $order->save();
            Db::commit();
        }catch (Exception $e){
            Db::callback();
            $this->error($e->getMessage());
        }
        $this->success('ok');
    }

    /**
     * 余额列表
     */
    public function balanceList()
    {
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');

        $query = BalanceRecordModel::with(['task_order'=>['task'=>['category']]])
            ->where('pilot_id', $pilot['id'])
            ->order('id desc');
        $list = get_list($query);
        // 数据清洗
        foreach ($list['list'] as &$vo){
            if ($vo['type'] == 1){
                $vo['task'] = [
                    'name' => $vo['task_order']['task']['name'] ?? '',
                    'category_name' => $vo['task_order']['task']['category']['name'] ?? ''
                ];
            }
            unset($vo['task_order']);
        }
        $this->success('ok', $list);
    }


    /**
     * 余额提现申请
     */
    public function balanceToCashApply(){
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');
        if (empty($pilot['phone'])) $this->error('请先登录');

        $apply = ToCashModel::where('pilot_id', $pilot['id'])->where('status', 0)->find();
        if (!empty($apply)) $this->error('您有待审核的提现申请，请耐心等待');

        $input = $this->request->post();
        $data = [
            'realname' => $input['realname'] ?? '',
            'bank_name' => $input['bank_name'] ?? '',
            'branch_nane' => $input['branch_nane'] ?? '',
            'card_no' => $input['card_no'] ?? '',
            'money' => floatval($input['money'] ?? 0),
            'status' => 0,
            'pilot_id' => $pilot['id'],
        ];
        if (empty($data['realname'])) $this->error('请填写持卡人姓名');
        if (empty($data['bank_name'])) $this->error('请填写银行名称');
        if (empty($data['branch_nane'])) $this->error('请填写银行支行名称');
        if (empty($data['card_no'])) $this->error('请填写银行卡号');
        if (empty($data['money'])) $this->error('提现金额不能为空');

        Db::startTrans();
        try {
            $pilot = PilotModel::where('id', $pilot['id'])->lock(true)->find();
            if ($pilot->balance < $data['money']) $this->error('余额不足');
            // 创建余额申请
            $to_cash = ToCashModel::create($data);
            // 扣除余额
            BalanceRecordModel::create([
                'pilot_id' => $pilot->id,
                'type' => BalanceRecordModel::TYPE__OUT_WITHDRAW,
                'amount' => - $to_cash->money,
                'before' => $pilot->balance,
                'after' => $pilot->balance - $to_cash->money,
                'remark' => '',
            ]);
            $pilot->balance -= $to_cash->money;
            $pilot->save();
            Db::commit();
        }catch (Exception $e){
            Db::callback();
            $this->error($e->getMessage());
        }
        $this->success('ok');
    }

    /**
     * 提现申请列表
     */
    public function toCashApplyList(){
        $pilot = request()->pilot;
        if (empty($pilot)) $this->error('接口权限错误');

        $query = ToCashModel::where('pilot_id', $pilot['id'])
            ->order('id desc');
        $list = get_list($query);
        $this->success('ok', $list);
    }
}